package com.fishingwithme.android.data.location

import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Looper
import android.util.Log
import androidx.core.content.ContextCompat
import com.fishingwithme.android.data.model.Position
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.coroutines.resume

/**
 * 优化版位置服务：提升定位速度和可靠性
 * 改进点：
 * 1. 优化定位提供者优先级和超时策略
 * 2. 改进位置验证逻辑以提高速度
 * 3. 增加快速返回机制
 * 4. 优化参数配置以提高速度
 */
@Singleton
class LocationService @Inject constructor(
    @ApplicationContext private val context: Context
) {

    // 定位核心管理器（懒加载，避免提前初始化）
    private val locationManager: LocationManager by lazy {
        context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    }

    // 核心配置（优化后的参数，优先考虑速度）
    private val LOCATION_TIMEOUT = 10_000L    // 总超时：10秒（减少一半时间）
    private val MIN_ACCURACY = 100f          // 最小精度：100米内（放宽精度要求）
    private val LOCATION_VALID_DURATION = 10 * 60 * 1000L // 位置有效期：10分钟（延长有效期）
    
    // 新增配置：更快的定位参数
    private val MIN_UPDATE_INTERVAL = 1_000L // 1秒更新间隔（更快响应）
    private val MIN_DISTANCE = 5f            // 5米距离变化（更敏感）

    // 定位提供者优先级（优化：Fused > GPS > Network，Fused通常最快）
    private val PREFERRED_PROVIDERS = listOf(
        LocationManager.FUSED_PROVIDER,
        LocationManager.GPS_PROVIDER,
        LocationManager.NETWORK_PROVIDER
    )

    /**
     * 核心方法：获取当前有效地理位置
     * 优化逻辑：优先快速获取位置（包括缓存）→ 快速新鲜定位 → 失败返回异常
     */
    @SuppressLint("MissingPermission")
    suspend fun getCurrentLocation(): Result<Position> = withContext(Dispatchers.IO) {
        return@withContext try {
            // 1. 前置检查：权限 + 定位服务是否可用
            if (!hasLocationPermissions()) {
                return@withContext Result.failure(SecurityException("位置权限未授予"))
            }
            if (!isLocationServiceEnabled()) {
                return@withContext Result.failure(Exception("位置服务未开启"))
            }

            // 2. 优先尝试「有效缓存定位」（最快获取位置的方式）
            val lastKnownLocation = getValidLastKnownLocation()
            if (lastKnownLocation != null) {
                val position = Position(lastKnownLocation.latitude, lastKnownLocation.longitude)
                Log.d("LocationService", "使用缓存位置：${position.latitude}, ${position.longitude}（精度：${lastKnownLocation.accuracy}米，提供者：${lastKnownLocation.provider}）")
                return@withContext Result.success(position)
            }

            // 3. 缓存定位失败 → 尝试获取「新鲜定位」
            val freshLocation = requestFreshLocation()
            if (freshLocation != null && isLocationValid(freshLocation)) {
                val position = Position(freshLocation.latitude, freshLocation.longitude)
                Log.d(
                    "LocationService",
                    "获取新鲜位置：${position.latitude}, ${position.longitude}（精度：${freshLocation.accuracy}米，提供者：${freshLocation.provider}）"
                )
                return@withContext Result.success(position)
            }

            // 4. 所有方案失败
            Result.failure(Exception("无法获取有效位置，请检查GPS/网络并确保在户外开阔区域"))

        } catch (e: Exception) {
            Log.e("LocationService", "获取位置异常", e)
            Result.failure(e)
        }
    }

    // -------------------------- 内部工具方法（优化后的核心逻辑） --------------------------
    /**
     * 检查是否有位置权限（精确/粗略二选一）
     */
    private fun hasLocationPermissions(): Boolean {
        val hasFine = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) == android.content.pm.PackageManager.PERMISSION_GRANTED

        val hasCoarse = ContextCompat.checkSelfPermission(
            context,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        ) == android.content.pm.PackageManager.PERMISSION_GRANTED

        return hasFine || hasCoarse
    }

    /**
     * 检查定位服务是否开启（至少一个提供者可用）
     */
    private fun isLocationServiceEnabled(): Boolean {
        return try {
            PREFERRED_PROVIDERS.any { locationManager.isProviderEnabled(it) }
        } catch (e: Exception) {
            false
        }
    }

    /**
     * 验证位置是否有效（优化：更宽松的验证以提高速度）
     */
    private fun isLocationValid(location: Location): Boolean {
        // 检查位置对象是否为空
        if (location.provider == null) return false
        
        // 经纬度范围合法
        val isCoordValid = location.latitude in -90.0..90.0 && location.longitude in -180.0..180.0
        
        // 精度达标（放宽到100米，但仍可接受）
        val isAccurate = location.hasAccuracy() && location.accuracy <= MIN_ACCURACY
        
        // 未过期（延长到10分钟）
        val isRecent = System.currentTimeMillis() - location.time <= LOCATION_VALID_DURATION
        
        // 过滤模拟器默认位置（Google HQ）
        val isNotEmulatorDefault =
            !(location.latitude in 37.0..38.0 && location.longitude in -123.0..-121.0)
        
        // 过滤无效位置（0,0坐标）
        val isNotZeroLocation = !(location.latitude == 0.0 && location.longitude == 0.0)

        return isCoordValid && isAccurate && isRecent && isNotEmulatorDefault && isNotZeroLocation
    }

    /**
     * 请求新鲜定位（优化：更快的响应和超时机制）
     */
    @SuppressLint("MissingPermission")
    private suspend fun requestFreshLocation(): Location? =
        suspendCancellableCoroutine { continuation ->
            var isResolved = false
            var currentListener: LocationListener? = null
            val scope = CoroutineScope(Dispatchers.Main)
            try {
                // 并行尝试所有提供者，第一个返回有效位置的获胜
                scope.launch {
                    for (provider in PREFERRED_PROVIDERS) {
                        if (isResolved || !locationManager.isProviderEnabled(provider)) continue

                        try {
                            // 实现 LocationListener
                            val listener = object : LocationListener {
                                override fun onLocationChanged(location: Location) {
                                    if (!isResolved && isLocationValid(location)) {
                                        isResolved = true
                                        currentListener = null
                                        try {
                                            locationManager.removeUpdates(this)
                                        } catch (e: Exception) {
                                            // Ignore
                                        }
                                        // Check if continuation is active before resuming
                                        if (continuation.isActive) {
                                            continuation.resume(location)
                                        }
                                    }
                                }

                                // 必要回调实现
                                override fun onProviderDisabled(provider: String) {
                                    // 如果当前提供者被禁用，尝试下一个
                                    if (!isResolved && this == currentListener) {
                                        Log.d("LocationService", "Provider $provider 被禁用")
                                    }
                                }

                                override fun onProviderEnabled(provider: String) {}

                                override fun onStatusChanged(
                                    provider: String?,
                                    status: Int,
                                    extras: android.os.Bundle?
                                ) {
                                }

                                // 兼容 Android 8.0+ 的新回调
                                override fun onLocationChanged(locations: MutableList<Location>) {
                                    super.onLocationChanged(locations)
                                    locations.firstOrNull()?.let { onLocationChanged(it) }
                                }
                            }

                            currentListener = listener
                            locationManager.requestLocationUpdates(
                                provider,
                                MIN_UPDATE_INTERVAL, // 更快的更新间隔
                                MIN_DISTANCE,        // 更敏感的距离变化
                                listener,
                                Looper.getMainLooper()
                            )

                        } catch (e: Exception) {
                            Log.w("LocationService", "Provider $provider 失败：${e.message}")
                        }
                    }

                    // 快速超时：3秒（大幅减少等待时间）
                    delay(3000)
                    if (!isResolved) {
                        // 清理所有监听器
                        currentListener?.let {
                            try {
                                locationManager.removeUpdates(it)
                            } catch (e: Exception) {
                                // Ignore
                            }
                        }
                        // Check if continuation is active before resuming
                        if (continuation.isActive) {
                            continuation.resume(null)
                        }
                    }
                }

                // 总超时：10秒
                scope.launch {
                    delay(LOCATION_TIMEOUT)
                    if (!isResolved) {
                        isResolved = true
                        currentListener?.let {
                            try {
                                locationManager.removeUpdates(it)
                            } catch (e: Exception) {
                                // Ignore
                            }
                        }
                        // Check if continuation is active before resuming
                        if (continuation.isActive) {
                            continuation.resume(null)
                        }
                    }
                }

                // 协程取消时清理资源
                continuation.invokeOnCancellation {
                    isResolved = true
                    currentListener?.let {
                        try {
                            locationManager.removeUpdates(it)
                        } catch (e: Exception) {
                            // Ignore
                        }
                    }
                    scope.cancel()
                }
            }catch (e: Exception ) {
                //Ignore
            }
        }

    /**
     * 获取有效缓存定位（优化：最快获取位置的方式）
     */
    @SuppressLint("MissingPermission")
    private fun getValidLastKnownLocation(): Location? {
        return try {
            PREFERRED_PROVIDERS
                .mapNotNull { provider ->
                    if (locationManager.isProviderEnabled(provider)) {
                        locationManager.getLastKnownLocation(provider)
                    } else null
                }
                .filter { isLocationValid(it) }
                .maxByOrNull { it.time } // 取最新的有效缓存（而不是最精确的）
                ?.also { Log.d("LocationService", "找到${PREFERRED_PROVIDERS.size}个提供者的缓存位置") }

        } catch (e: Exception) {
            Log.w("LocationService", "获取缓存位置失败：${e.message}")
            null
        }
    }
}